package com.xxxtea.util;

import lombok.experimental.UtilityClass;

/**
 * 计算工具类
 * 
 * 提供各种业务计算相关的工具方法，包括：
 * - 配送时间计算
 * - 配送费用计算
 * - 其他业务计算功能
 * 
 * 使用@UtilityClass注解，表示这是一个工具类，不能被实例化
 * 
 * @author badman
 * @since 1.0.0
 */
@UtilityClass
public class CalUtils {

	/**
	 * 根据配送距离计算预计配送时间
	 * 
	 * 计算规则：
	 * - 3公里内基础配送时间：15分钟
	 * - 超出3公里部分：每公里增加5分钟
	 * - 不足1公里按1公里计算
	 * - 最长配送时间不超过60分钟
	 *
	 * @param distance 配送距离，单位：公里
	 * @return 预计配送时间，单位：分钟
	 * @throws IllegalArgumentException 当距离为负数时抛出异常
	 */
	public static int calculateDeliveryTime(double distance) {
		// 参数校验：距离不能为负数
		if (distance < 0) {
			throw new IllegalArgumentException("配送距离不能为负数");
		}

		// 基础配送时间（3公里内）
		int baseTime = 15;

		// 每公里增加的时间
		double timePerKm = 5;

		// 超过3公里部分的距离
		double extraDistance = Math.max(0, distance - 3);

		// 计算总时间（不足1公里按1公里计算）
		int totalTime = baseTime + (int) Math.ceil(extraDistance * timePerKm);

		// 最长不超过60分钟
		return Math.min(totalTime, 60);
	}

	/**
	 * 外卖配送费计算
	 * 
	 * 计算规则：
	 * - 3公里内：基础配送费2元
	 * - 超出3公里：每超出1公里增加1元
	 * - 最高配送费：15元
	 * - 不足1公里按1公里计算
	 * 
	 * @param distance 配送距离，单位：公里
	 * @return 配送费用，单位：元
	 * @throws IllegalArgumentException 当距离为负数时抛出异常
	 */
	public double calculateDeliveryFee(double distance) {
		// 参数校验：距离不能为负数
		if (distance < 0) {
			throw new IllegalArgumentException("距离不能为负数");
		}

		// 基础参数设置
		double baseFee = 2.0;         // 3公里内基础配送费
		double freeDistance = 3.0;    // 免费配送距离（公里）
		double stepFee = 1.0;         // 每超出1公里增加的费用
		double maxFee = 15.0;         // 最高配送费

		// 3公里内按基础配送费计算
		if (distance <= freeDistance) {
			return baseFee;
		}

		// 超出3公里部分计算附加费用
		double extraDistance = distance - freeDistance;
		double extraFee = Math.ceil(extraDistance) * stepFee;

		// 总费用 = 基础费用 + 附加费用（不超过最高配送费）
		return Math.min(baseFee + extraFee, maxFee);
	}
}
